<template>
  <div class="scroll-load">
    <ul class="list">
      <li v-for="d in list" :key="d">{{ d }}</li>
    </ul>
    <div class="loading">正在加载...</div>
  </div>
</template>

<script>
const ajax = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(new Array(5).fill(0).map(() => Math.random()));
    }, Math.random() * 1000);
  });
};

export default {
  data() {
    return {
      loading: false,
      list: [],
    };
  },
  methods: {
    onScroll() {
      console.log("发生滚动了");
      // this.needLoad();
      if (!this.loading && this.needLoad()) {
        this.getList();
      }
    },
    // 判断是否需要加载，底部的正在加载dom和可视区顶部的距离小于可视区高度
    needLoad() {
      // const clientHeight = document.documentElement.clientHeight;
      const clientHeight = window.innerHeight;
      console.log('h', clientHeight)
      const { top } = document
        .querySelector(".loading")
        .getBoundingClientRect();
      console.log(top);
      return top <= clientHeight + 100;
    },
    getList() {
      this.loading = true;
      ajax().then((data) => {
        // this.list = this.list.concat(data);
        // 展开运算符可以合并对象或者数组
        this.list = [...this.list, ...data];
        this.loading = false;

        // 判断数据是否占满可视区了，就是判断needLoad是不是false
        // setTimeout 是为了保证前面给 list 增加数据导致的视图已经完成了
        setTimeout(() => {
          if (this.needLoad()) {
            this.getList();
          }
        }, 0);
      });
    },
  },
  // 创建生命周期
  mounted() {
    window.addEventListener("scroll", this.onScroll);
    this.getList();
  },
  // 相当于小程序的 onUnload
  beforeDestroy() {
    window.removeEventListener("scroll", this.onScroll);
  },
};
</script>

<style lang="sass">
body
  // height: 3000px
  .scroll-load
    text-align: center
    .list
      width: 500px
      margin: 0 auto
    li
      line-height: 50px
      &:nth-child(odd)
        background: #f0c0f0
      &:nth-child(even)
        background: #c0f0c0
</style>
